package com.example.search.service.impl;

import com.example.model.search.dto.UserSearchDto;
import com.example.model.search.pojo.SearchArticleVo;
import com.example.search.service.ArticleSearchService;
import com.example.search.service.UserSearchService;
import com.example.utils.thread.UserThreadLocal;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.data.elasticsearch.core.query.highlight.Highlight;
import org.springframework.data.elasticsearch.core.query.highlight.HighlightField;
import org.springframework.data.elasticsearch.core.query.highlight.HighlightFieldParameters;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class ArticleSearchServiceImpl implements ArticleSearchService {
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    private UserSearchService userSearchService;

    @Override
    public Page< SearchArticleVo > search(UserSearchDto userSearchDto, Long page, Long pageSize) {
        // 1、 构建查询条件
        Criteria criteria = new Criteria();
        /*criteria = criteria.and(new Criteria());
        criteria = criteria.or(new Criteria("articleTitle").contains(userSearchDto.getSearchWords()))
                .or(new Criteria("content").contains(userSearchDto.getSearchWords()));
        criteria = criteria.and(new Criteria("publishTime").greaterThan(userSearchDto.getMinBehotTime()));*/

        // 关键词为空，查询全部
        if (StringUtils.isEmpty(userSearchDto.getSearchWords())) {
            criteria = criteria.and(new Criteria());
        } else {
            // 关键词不为空，查询包含关键词的
            userSearchService.insert(userSearchDto.getSearchWords(), UserThreadLocal.getUser().getUserId());
            criteria = criteria.or(new Criteria("articleTitle").contains(userSearchDto.getSearchWords()))
                    .or(new Criteria("content").contains(userSearchDto.getSearchWords()));
        }
        // 添加时间过滤条件
        if (userSearchDto.getMinBehotTime() != null) {
            // 关键词不为空，查询包含关键词的
            criteria = criteria.and(new Criteria("publishTime").greaterThan(userSearchDto.getMinBehotTime()));
        }

        // 2、 设置分页
        PageRequest pageRequest = PageRequest.of(page.intValue(), pageSize.intValue());

        // 3、设置高亮
        List< HighlightField > highlightFieldList = new ArrayList<>();
        HighlightField highlightField = new HighlightField("articleTitle", HighlightFieldParameters.builder().withPreTags("<font style='color:red; font-size: inherit;'>").withPostTags("</font>").build());
        highlightFieldList.add(highlightField);
        Highlight highlight = new Highlight(highlightFieldList);
        HighlightQuery highlightQuery = new HighlightQuery(highlight, SearchArticleVo.class);

        // 4、构建查询
        CriteriaQueryBuilder builder = new CriteriaQueryBuilder(criteria)
                .withHighlightQuery(highlightQuery)
                .withPageable(pageRequest);
        CriteriaQuery query = new CriteriaQuery(builder);

        // 5、执行查询
        SearchHits<SearchArticleVo> searchHits = elasticsearchTemplate.search(query, SearchArticleVo.class);
        List<SearchArticleVo> articles = searchHits.getSearchHits().stream()
                .map(hit -> {
                    SearchArticleVo article = hit.getContent();
                    // 处理高亮
                    if (hit.getHighlightFields().containsKey("articleTitle")) {
                        String highlightedTitle = hit.getHighlightFields().get("articleTitle").toString();
                        article.setArticleTitle(highlightedTitle);
                    } else {
                        article.setArticleTitle(article.getArticleTitle());
                    }
                    return article;
                })
                .toList();
        long total = searchHits.getTotalHits();
        // 返回查询结果
        return new PageImpl<>(articles, pageRequest, total);
    }
}
